#ifndef PARSE_H
#define PARSE_H

#include "lexer.h"
#include "AstNode.h"
#include <list>
#include <unordered_map>
#include "Type.h"

class Parser {
private:
    Lexer& Lex;
    std::list<std::shared_ptr<Var>> *Locals{nullptr};       // 语法分析中已经出现的局部变量
    std::unordered_map<std::string_view, std::shared_ptr<Var>> LocalsMap;

public:
    Parser(Lexer& lex): Lex(lex) {}
    std::shared_ptr<ProgramAstNode> Parse();     
private:
    std::shared_ptr<AstNode> ParseFunction();

    std::shared_ptr<Type> ParseDeclarationSpec();
    std::shared_ptr<Type> ParseDeclarator(std::shared_ptr<Type> baseType, std::shared_ptr<Token> &token);
    std::shared_ptr<Type> ParseTypeSuffix(std::shared_ptr<Type> baseType);

    std::shared_ptr<AstNode> ParseFuncCall(std::shared_ptr<Token> nameTok);
    std::shared_ptr<AstNode> ParseStatement();
    std::shared_ptr<AstNode> ParseExpr();
    std::shared_ptr<AstNode> ParseAssignExpr();
    std::shared_ptr<AstNode> ParseEqualExpr();
    std::shared_ptr<AstNode> ParseRelationExpr();
    std::shared_ptr<AstNode> ParseAddExpr();
    std::shared_ptr<AstNode> ParseMultiExpr();
    std::shared_ptr<AstNode> ParseUnaryExpr();
    std::shared_ptr<AstNode> ParsePostSuffixExpr();
    std::shared_ptr<AstNode> ParsePrimaryExpr();
    
    bool IsTypeName();

    std::shared_ptr<AstNode> MakeVarNode(std::shared_ptr<Var> var, std::shared_ptr<Token> tok);

    std::shared_ptr<Var> FindLocalVar(std::string_view name);
    std::shared_ptr<Var> MakeLocalVar(std::string_view name, std::shared_ptr<Type> ty);

};

#endif // !PARSE_H